

import java.io.IOException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;

public class Server implements NetworkEventListener, NetworkInterface {
	private int port;
	private Registry registry;
	private TicTacRemoteInterface serverRIObject;
	private TicTacRemoteInterface clientRIObject;
	private Game game;
	
	public Server(int port, Game game){
		System.setSecurityManager(new LiberalSecurityManager());
		this.port = port;
		this.game = game;
		serverRIObject = TicTacRemoteObject.createTicTacRIObject("serverObj", this);
		setUpServer();
	}
	
	public int getPort(){
		return port;
	}
	
	private void setUpServer(){
		try {
			createRegistryAndBindRIObject();
		} catch (RemoteException e) {
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	private void createRegistryAndBindRIObject() throws RemoteException, IOException {
		registry = LocateRegistry.createRegistry(port);
		System.out.println("Registry created");

		TicTacRemoteInterface stub = (TicTacRemoteInterface) UnicastRemoteObject.exportObject(serverRIObject, port);
		registry.rebind(serverRIObject.myId(), stub);
		System.out.println("Binded an object inside registry");
		System.out.println("Now we are waiting for a client....");
	}
	

	@Override
	public void event(NetworkEvent event) {
		System.out.println("Event was triggered");
		if (event instanceof ConnectionEvent) {
			System.out.println("\t Type: ConnectionEvent");
			try {
				System.out.println("Trying to bound clientRIOject");
				String objectID = ((ConnectionEvent) event).getID();
				clientRIObject = (TicTacRemoteInterface) TicTacRemoteObject.lookupRIObject(objectID, registry);
				
				System.out.println("Bound clientRIObject");
				clientRIObject.print("yeah baby");
			} catch (RemoteException e) {
				System.out.println("Could not lookup the remote interface object in event");
				e.printStackTrace();
			}
		}
		else if (event instanceof MoveEvent){
			System.out.println("\t Type: MoveEvent");
			int row = ((MoveEvent) event).getRow();
			int col = ((MoveEvent) event).getCol();
			game.placeMark(row, col);
		}
		else if (event instanceof DisconnectEvent){
			System.out.println("\t Type: DisconnectEvent");
			// TODO Logics for ending game
		}
		
	}

	public void doMove(int row, int column)
	{
		try
		{
			System.out.print("Trying to send move("+row+", "+column+")...");
			clientRIObject.receivedMove(row, column);
			
			System.out.println("SUCCESS");
		} catch (RemoteException e)
		{
			System.out.println("FAILED");
			e.printStackTrace();
		}
	}

	@Override
	public void disconnect()
	{
		try {
			System.out.print("Trying to disconnect... ");
			clientRIObject.disconnect();
			System.out.println("SUCCESS");
		} catch (RemoteException e) {
			System.out.println("FAILED");
			e.printStackTrace();
		}
	}
}